package com.sk.ccflower.server.lib.sysUtils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.sk.ccflower.lib.commonUtils.StringUtil;
import com.sk.ccflower.server.lib.sysBeans.CpuLoadBean;
import com.sk.ccflower.server.lib.sysBeans.CpuStatBean;
import com.sk.ccflower.server.lib.sysBeans.ProcCpuLoadBean;
import com.sk.ccflower.server.lib.sysBeans.ProcStatBean;

/**
 * @author eunwoogi
 * @since 2009. 11. 11.
 */
public class SysResCollectImpl_Linux implements SysResCollectFacade {
	
	public int getPid( String name ) throws Exception {
		try {
			int pid = -1;
			Runtime rt = Runtime.getRuntime();
			//String[] cmd = { "sh", "-c", "ps -ef | grep "+name+" | grep -v ProcManager | grep -v grep | awk '{print $2}'" };
			String[] cmd = { "sh", "-c", "ps -ef | grep "+name+" | grep -v grep | awk '{print $2}'" };
            Process proc = rt.exec( cmd );
            
            InputStream is = proc.getInputStream();
            InputStreamReader isr = new InputStreamReader( is );
            BufferedReader br = new BufferedReader( isr );
            
            String pidStr = br.readLine();
            if ( null == pidStr ) {
            	
            } else {
            	pid = new Integer(pidStr).intValue();
            }
            
            br.close();
            
            proc.waitFor();
            proc.destroy();
            
            return pid;
		} catch ( Exception e ) {
			e.printStackTrace();
		}
		
		return -1;
	}
	
	public String getCpuStat() throws Exception {
		Runtime rt = Runtime.getRuntime();
		String[] cmd = { "sh", "-c", "cat /proc/stat" };
        Process proc = rt.exec( cmd );
        
        InputStream is = proc.getInputStream();
        InputStreamReader isr = new InputStreamReader( is );
        BufferedReader br = new BufferedReader( isr );
        
        String statStr = br.readLine();
        
        br.close();
        
        proc.waitFor();
        proc.destroy();
        
		return statStr;
	}
	
	public CpuStatBean parseCpuStat( String stat ) throws Exception {
		String[] values = StringUtil.toStringArray( stat, " " );
		CpuStatBean data = new CpuStatBean();
		
		data.user = new Long( values[2] ).longValue();
		data.nice = new Long( values[3] ).longValue();
		data.system = new Long( values[4] ).longValue();
		data.idle = new Long( values[5] ).longValue();
		data.total = data.user + data.nice + data.system + data.idle;
		
		return data;
	}
	
	public CpuLoadBean getCpuLoad( CpuStatBean oldData, CpuStatBean newData ) throws Exception {
		CpuLoadBean load = new CpuLoadBean();
		
		load.user = (float) ((newData.user - oldData.user) * 100) / (newData.total - oldData.total);
	    load.system = (float) ((newData.system - oldData.system) * 100) / (newData.total - oldData.total);
	    
		return load;
	}
	
	public String getProcStat( int pid ) throws Exception {
		if ( pid == -1 )	return null;
		
		Runtime rt = Runtime.getRuntime();
		String[] cmd = { "sh", "-c", "cat /proc/"+pid+"/stat" };
        Process proc = rt.exec( cmd );
        
        InputStream is = proc.getInputStream();
        InputStreamReader isr = new InputStreamReader( is );
        BufferedReader br = new BufferedReader( isr );
        
        String statStr = br.readLine();
        
        br.close();
        
        proc.waitFor();
        proc.destroy();
        
		return statStr;
	}
	
	public ProcStatBean parseProcStat( String stat ) throws Exception {
		ProcStatBean data = new ProcStatBean();
		
		if ( null == stat )	return data;
		
		String[] values = StringUtil.toStringArray( stat, " " );
		
		data.name = new String( values[1] );
		data.ucpu = new Long( values[13] ).longValue();
		data.scpu = new Long( values[14] ).longValue();
		data.vmem = new Long( values[22] ).longValue();
		data.rmem = new Long( values[23] ).longValue();
		data.rmem *= 4096;	// default page size(4K)
		
		return data;
	}
	
	public ProcCpuLoadBean getProcCpuLoad( ProcStatBean oldProc, ProcStatBean newProc, CpuStatBean oldCpu, CpuStatBean newCpu ) throws Exception {
		ProcCpuLoadBean procLoad = new ProcCpuLoadBean();
		CpuLoadBean cpuLoad = getCpuLoad( oldCpu, newCpu );
		
		if ( (newProc.ucpu == oldProc.ucpu) || (newCpu.user == oldCpu.user) ) {
			procLoad.user = 0.0f;
		} else {
			procLoad.user = ((float) (newProc.ucpu - oldProc.ucpu) / (float) (newCpu.user - oldCpu.user) * 100);
			procLoad.user *= (cpuLoad.user / 100);
		}
		
		if ( (newProc.scpu == oldProc.scpu) || (newCpu.system == oldCpu.system) ) {
			procLoad.system = 0.0f;
		} else {
			procLoad.system = ((float) (newProc.scpu - oldProc.scpu) / (float) (newCpu.system - oldCpu.system) * 100);
			procLoad.system *= (cpuLoad.system / 100);
		}
		
		if ( procLoad.user > 100 )		procLoad.user = 100;
		if ( procLoad.system > 100 )	procLoad.system = 100;
		
		if ( procLoad.user < 0 )		procLoad.user = 0;
		if ( procLoad.system < 0 )		procLoad.system = 0;
		
		return procLoad;
	}
	
}
